// let a=0,
//     b=0;
// function A(a){
//     A=function(b){
//         alert(a+b++);
//     };
//     alert(a++);
// }
// A(1); // "1"
// A(2);  // "4"

// 变量提升[预解析]
//  在“当前上下文”代码自上而下执行“之前”，浏览器会把所有待“var/function”关键字得进行提前得声明或者定义
//    + 带var的知识提前声明
//    + 带function的是提前声明+赋值（定义）
// EC(G)
//  变量提升：
//     var a;
//     fn1=0x000;[[scope]:EC(G)]
//     var fn2
// console.log(a); // undefined
// fn1();
// var a= 10;  // 全局a=10
// function fn1(){  // 直接跳过[变量提升截断已经创建过了]
//     // EC(FN1)
//     //  作用域链：<EC(FN1),EC(G)>
//     //  形参赋值：--
//     //  变量提升：
//     //    var a;
//     console.log('fn1') // 'fn1'
//     console.log(a); // undefined
//     var a = 20;   // 私有a=20
//     console.log(a);  // 20
// }
// fn1();
// fn2();  // Uncaught TypeError: fn2 is not a function
// var fn2 = function(){ // 函数表达式
//     console.log('fn2')
// }
// fn2();

//真实项目中推荐大家使用函数表达式的方式去创建函数 普通函数在变量提升阶段是声明+赋值，函数表达式只声明【函数表达式可以规范函数执行的顺序】
// const fn = function(){};
//  fn();

// 匿名函数具名化 [更规范一些]
// var fn = function sum() {
//     console.log('OK');
//     // sum = 100;//修改sum无效
//     // console.log(sum) //sum代表函数本身 具名化的名字可以在函数内部的上下文中使用，默认情况下，其值实不能被修改的
//     console.log(sum); //->undefined 虽然具名化的名字会在当前函数私有上下文中使用，当作私有变量处理，但是他的优先级比较低的
//     // 一旦出现同名的其它声明方式，则以其他方式为主
//     var sum;
// };
// fn();
// sum(); //Uncaught ReferenceError: sum is not defined
// 匿名函数具名化，设置的函数名不能再函数以外使用[因为并没有在当前上下文声明这个变量]

// "use strict";// ->让js使用严格模式
// // 自执行函数
// (function anonyous(x){
//     if(x<0) return;
//     console.log(x);
//     // 递归调用
//     // console.log(arguments.callee); // 函数本身
//     //开启严格模式则报错 Uncaught TypeError: "use strict" is not a function
//     // arguments.callee(x-1)
//     anonyous(x-1);
// })(10)

// EC(G)
//  变量提升：
//  fn=0x000 [[scope]:EC(G)]
//    [老版本浏览器中]
//    sum=0x001  [[scope]:EC(G)]
//    [新版本浏览器中]
//    sum;
console.log(sum,fn); // undefined ƒ fn(){}
function fn(){}
if(1 !==1 ){
    function sum(){}
}
